package prickworlds.game.templates;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import prickworlds.Prickworlds;
import prickworlds.game.DropItem;
import prickworlds.game.DropItem.DropTemplate;
import prickworlds.graphics.FullTexture;
import prickworlds.graphics.Texture;
import prickworlds.util.Path;

/**
 * @author Faruk Acibal
 * @author Richard Dziambor
 * @author Christian Holzreuter
 * @author Nicolas Winkler
 */
public class MapTemplate extends Template {
	/**
	 * the width and height of a single cell
	 */
	int cellSize = 64;

	FullTexture texturePack;

	/**
	 * width of the map
	 */
	private int width;

	/**
	 * height of the map
	 */
	private int height;

	/**
	 * contains all the walls...
	 */
	public RobotTemplate[] robotTemplates;
	public WeaponTemplate[] weaponTemplates;
	public DropTemplate[] dropTypes;

	public MapTemplate() {
		// 50.0f, 0.0f);
		// weaponTemplates[1] = new WeaponTemplate("enemy Gun", 0.15f, 100, 10,
		// 20.0f, 0.0f);

		robotTemplates = new RobotTemplate[2];

		robotTemplates[0] = new RobotTemplate();
		robotTemplates[0].upperTexture = FullTexture
				.loadImage(Prickworlds.class
						.getResourceAsStream("data/RoboterOben.png"));
		robotTemplates[0].lowerTexture = FullTexture
				.loadImage(Prickworlds.class
						.getResourceAsStream("data/RoboterUnten.png"));
		robotTemplates[0].maxSpeed = 5.0f;

		robotTemplates[1] = new RobotTemplate();
		robotTemplates[1].upperTexture = FullTexture
				.loadImage(Prickworlds.class
						.getResourceAsStream("data/RoboterOben.png"));
		robotTemplates[1].lowerTexture = FullTexture
				.loadImage(Prickworlds.class
						.getResourceAsStream("data/RoboterUnten.png"));
		robotTemplates[1].maxSpeed = 25.0f;

		((FullTexture) robotTemplates[1].upperTexture)
				.setQuality(FullTexture.Quality.LINEAR);
		((FullTexture) robotTemplates[1].lowerTexture)
				.setQuality(FullTexture.Quality.LINEAR);

		dropTypes = new DropItem.DropTemplate[4];
		dropTypes[0] = new DropItem.DropTemplate(
				DropItem.DropTemplate.Type.LIFE_UP);
		dropTypes[1] = new DropItem.DropTemplate(
				DropItem.DropTemplate.Type.DAMAGE_UP);
		dropTypes[2] = new DropItem.DropTemplate(
				DropItem.DropTemplate.Type.HEAL_LIFE);
		dropTypes[3] = new DropItem.DropTemplate(
				DropItem.DropTemplate.Type.RELOAD_UP);

		texturePack = FullTexture.loadImage(Prickworlds.class
				.getResourceAsStream("data/graphics.png"));
	}

	/**
	 * creates textures for walls
	 * 
	 * @param side
	 *            <ul>
	 *            <li>0 for top wall texture</li>
	 *            <li>1 for right wall texture</li>
	 *            <li>2 for bottom wall texture</li>
	 *            <li>3 for left wall texture</li>
	 *            <li>4 for lower left corner wall texture</li>
	 *            <li>5 for upper left corner wall texture</li>
	 *            <li>6 for upper right corner wall texture</li>
	 *            <li>7 for lower right corner wall texture</li>
	 *            </ul>
	 */
	public Texture[] createWallTextures(int side) {
		return new Texture[] {
				texturePack.getChildTexture(0 * 32, side * 32, 32, 32),
				texturePack.getChildTexture(1 * 32, side * 32, 32, 32) };
	}

	public RobotTemplate getRobotTemplate(int i) {
		return robotTemplates[i];
	}

	public DropTemplate getDropType(int i) {
		return dropTypes[i];
	}

	public static MapTemplate loadMapTemplate(String filePath) {
		Element e = Template.createElement(filePath);
		MapTemplate mt = new MapTemplate();

		try {
			try {
				Element bounds = (Element) e.getElementsByTagName("bounds")
						.item(0);
				mt.setWidth(Integer.parseInt(bounds.getAttribute("width")));
				mt.setHeight(Integer.parseInt(bounds.getAttribute("height")));
			} catch (RuntimeException ex) {
				ex.printStackTrace();
			}

			try {
				Element weap = (Element) e.getElementsByTagName("weapons")
						.item(0);

				NodeList weapons = weap.getElementsByTagName("weapon");
				mt.weaponTemplates = new WeaponTemplate[weapons.getLength()];

				for (int i = 0; i < weapons.getLength(); i++) {
					Element weapon = (Element) weapons.item(i);
					Path path = new Path(filePath);
					path.removeLast();
					path.add(new Path(weapon.getAttribute("path")));
					mt.weaponTemplates[i] = WeaponTemplate
							.loadWeaponTemplate(path.getString());
				}
			} catch (RuntimeException ex) {
				ex.printStackTrace();
			}

			try {
				Element rob = (Element) e.getElementsByTagName("robots")
						.item(0);

				NodeList robots = rob.getElementsByTagName("robot");
				mt.robotTemplates = new RobotTemplate[robots.getLength()];

				for (int i = 0; i < robots.getLength(); i++) {
					Element robot = (Element) robots.item(i);
					Path path = new Path(filePath);
					path.removeLast();
					path.add(new Path(robot.getAttribute("path")));
					mt.robotTemplates[i] = RobotTemplate.loadRobotTemplate(
							path.getString(), mt);
				}
			} catch (RuntimeException ex) {
				ex.printStackTrace();
			}
		} catch (RuntimeException ex) {
			ex.printStackTrace();
		}

		return mt;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public WeaponTemplate getWeaponByName(String name) {
		for (int i = 0; i < weaponTemplates.length; i++) {
			WeaponTemplate wt = weaponTemplates[i];
			if (wt.getWeaponName().equals(name))
				return wt;
		}
		return null;
	}
}
